package sk.tramtatiri.pages.users;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Random;

import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;

import sk.tramtatiri.MySession;
import sk.tramtatiri.core.IConstants;
import sk.tramtatiri.data.dao.interfaces.FoodDao;
import sk.tramtatiri.data.dao.interfaces.InOutHelperDao;
import sk.tramtatiri.data.dao.interfaces.UserDao;
import sk.tramtatiri.data.dao.interfaces.UserFoodDao;
import sk.tramtatiri.data.dao.interfaces.UserRecipeDao;
import sk.tramtatiri.data.dataobjects.Food;
import sk.tramtatiri.data.dataobjects.InOutHelper;
import sk.tramtatiri.data.dataobjects.UserFood;

public class DietsPage extends UserPageTemplate {

	@SpringBean
	private FoodDao foodDao;
	@SpringBean
	private UserFoodDao userFoodDao;
	@SpringBean
	private UserDao userDao;
	@SpringBean
	private UserRecipeDao userRecipeDao;
	@SpringBean
	private InOutHelperDao inOutHelperDao;

	private TextField userCalories;
	private TextField numberOfMeals;
	private List<Food> foods = new ArrayList<Food>();
	private int[] weights;
	private String userCal;
	private List<IModel> models = new ArrayList<IModel>();

	public DietsPage() {

		final Form<?> form = new Form<Void>("formDiet");

		userCalories = new TextField("userCalories", Model.of(""));
		numberOfMeals = new TextField("numberOfMeals", Model.of(""));

		form.add(userCalories);
		form.add(numberOfMeals);
		
		form.add(new ListView<Food>("row", foods){

			@Override
			protected void populateItem(ListItem<Food> item) {
				item.add(new Label("foodName", Model.of("")));
				item.add(new Label("foodCalories", Model.of(0)));
				item.add(new Label("foodSaccharides", Model.of(0)));
				item.add(new Label("foodFats", Model.of(0)));
				item.add(new Label("foodProteins", Model.of(0)));
				item.add(new Label("foodWeight", Model.of(0)));
			}
			
		}.setVisible(false));
		
		form.add(new Label("totalCalories", Model.of(0)));
		form.add(new Label("totalSaccharides", Model.of(0)));
		form.add(new Label("totalFats", Model.of(0)));
		form.add(new Label("totalProteins", Model.of(0)));
		form.add(new Label("totalWeight", Model.of(0)));
		
		Calendar cal = Calendar.getInstance();
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
				cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		final Date date = new Date(cal.getTimeInMillis());
		
		Button button = new Button("submitBtn") {
			private static final long serialVersionUID = 1471100619667932161L;

			public void onSubmit() {
				for (int i = 0;i < foods.size();i++) {
					Food food = foods.get(i);
					UserFood userFood = new UserFood();
					
					userFood.setDate(date);
					userFood.setUser(userDao.load(((MySession) getSession())
							.getUserID()));
					userFood.setUserId(((MySession) getSession())
							.getUserID());

					userFood.setQuantity(weights[i]);
					userFood.setTotalCalories(Math.round((float)food.getCalories()*weights[i]/100));
					userFood.setFood(food);
					long idFood = food.getId();
					userFood.setFoodId(idFood);
					userFoodDao.save(userFood);
					
					userDao.load(((MySession) getSession()).getUserID())
							.getFoods().add(userFood);
					foodDao.load(idFood).getUsers().add(userFood);
				}
				int totalTodayRec = userRecipeDao.sumUserToday(((MySession)getSession()).getUserID());
				int totalTodayFood = userFoodDao.sumUserToday(((MySession)getSession()).getUserID());
				InOutHelper todayHelper = inOutHelperDao.findByUserToday(((MySession)getSession()).getUserID());
				if(todayHelper!=null)
					todayHelper.setCaloriesIn(totalTodayFood+totalTodayRec);
				else {
					InOutHelper newHelper = new InOutHelper();
					newHelper.setDate(date);
					newHelper.setCaloriesIn(totalTodayFood+totalTodayRec);
					newHelper.setUsrid(((MySession)getSession()).getUserID());
					inOutHelperDao.save(newHelper);
				}
				info("Jedalnicek bol pridany k zjedenym");
			};
		};

		if (((MySession) getSession()).hasPermission()) {
			button.setVisible(true);
		} else {
			button.setVisible(false);
		}

		form.add(button);

		form.add(new AjaxButton("cancelBtn") {
			private static final long serialVersionUID = 7593256656271989331L;

			@Override
			protected void onSubmit(AjaxRequestTarget target, Form<?> arg1) {
				generate();
				
				ListView<Food> list = new ListView<Food>("row", foods) {
					private static final long serialVersionUID = -8391229537728617441L;

					@Override
					protected void populateItem(ListItem<Food> item) {
						final Food food = (Food) item.getModelObject();
						int weight = weights[item.getIndex()];
						float times = (float)weight/100;
						
						final PageParameters parameters = new PageParameters();
						parameters.put("name", food.getName());
						BookmarkablePageLink bpl = new BookmarkablePageLink("linkToFood", FoodDetailPage.class, parameters);
						bpl.add(new Label("foodName", Model.of(food.getName())));
						item.add(bpl);
						item.add(new Label("foodCalories", Model.of(Math.round(food.getCalories()*times))));
						item.add(new Label("foodSaccharides", Model.of(Math.round(food.getSaccharides()*times))));
						item.add(new Label("foodFats", Model.of(Math.round(food.getFats()*times))));
						item.add(new Label("foodProteins", Model.of(Math.round(food.getProteins()*times))));
						item.add(new Label("foodWeight", Model.of(weight)));
					}
				};
				list.setVisible(true);
				form.addOrReplace(list);
				
				form.addOrReplace(new Label("totalCalories", Model.of(getTotCalories())));
				form.addOrReplace(new Label("totalSaccharides", Model.of(getTotSaccharides())));
				form.addOrReplace(new Label("totalFats", Model.of(getTotFats())));
				form.addOrReplace(new Label("totalProteins", Model.of(getTotProteins())));
				form.addOrReplace(new Label("totalWeight", Model.of(getTotWeights())));
				
				target.addComponent(form);
			}
		});

		add(form);
	}

	@Override
	public String getPageTitle() {
		return IConstants.PAGE_NAME + " - Jedalnicek";
	}

	private void generate() {
		foods.clear();
		Random random = new Random();
		String number = numberOfMeals.getDefaultModelObjectAsString();
		if(number.matches("\\d+")){
			for (int i = 0; i < Integer.valueOf(number) ; i++) {
				Food food = foodDao.load((long) random.nextInt(foodDao.countAll()) + 1);
				if (checkFood(food.getId())) {
					foods.add(food);
				} else {
					i--;
				}
			}
		}
		
		//zoradi od najmensieho po najvacsie (kalore)
		Collections.sort(foods, new Comparator<Food>(){
            public int compare(Food f1, Food f2) {
            	return (f1.getCalories() >= f2.getCalories() ? 1 : 0);
            }
        });
		
		weights = new int[foods.size()];
		int weight = 20;
		for(int i = weights.length; i > 0; i--){
			weights[i-1] = weight;
			weight = weight + 10;
		}
		
		userCal = userCalories.getDefaultModelObjectAsString();
		if(userCal.matches("\\d+")){
			int item = 0;
			boolean bool;
			boolean increment = true;
			do{
				bool = true;
				int totCalories = getTotCalories();
				if(Math.abs(Integer.valueOf(userCal)-totCalories) > 50){
					if(Integer.valueOf(userCal)-totCalories > 0){
						if(!increment){
							item = 0;
							increment = true;
						}
						//pridavat
						System.out.println("PRIDAVAT");
						weights[item] = weights[item] + 5;
						if(item < foods.size()-1){
							item++;
						}else{
							item = 0;
						}
					}else{
						if(increment){
							item = 0;
							increment = false;
						}
						//odoberat
						System.out.println("ODOBERAT");
						if(weights[item] > 5){
							weights[item] = weights[item] - 5;
						}
						if(item < foods.size()-1){
							item++;
						}else{
							item = 0;
						}
					}
				}else{
					bool = false;
				}
			}while(bool);
		}
		
	}

	private boolean checkFood(long id) {
		for (Food food : foods) {
			if (food.getId() == id) {
				return false;
			}
		}
		return true;
	};
	
	private int getTotCalories(){
		int totCalories = 0;
		for (int i = 0;i < foods.size();i++) {
			totCalories = totCalories + Math.round((float)foods.get(i).getCalories()*weights[i]/100);
		}
		System.out.println("WWWAAA  "+totCalories);
		return totCalories;
	}
	
	private int getTotWeights() {
		int weight = 0;
		for (int w : weights) {
			weight += w;
		}
		return weight;
	}
	
	private int getTotSaccharides() {
		int saccharides = 0;
		for (int i = 0;i < foods.size();i++) {
			saccharides += Math.round((float)foods.get(i).getSaccharides()*weights[i]/100);
		}
		return saccharides;
	}
	
	private int getTotFats() {
		int fats = 0;
		for (int i = 0;i < foods.size();i++) {
			fats += Math.round((float)foods.get(i).getFats()*weights[i]/100);
		}
		return fats;
	}
	
	private int getTotProteins() {
		int proteins = 0;
		for (int i = 0;i < foods.size();i++) {
			proteins += Math.round((float)foods.get(i).getProteins()*weights[i]/100);
		}
		return proteins;
	}
}
